﻿namespace MathVisualizer

module UserControls =

    open System.Drawing

    type mouseInfo(handle, event, position:PointF) =
        let mutable _handle = handle
        let mutable _event = event
        let mutable _pos = position
    
        //UNUSED. Specifica se l'evento deve essere ancora gestito.
        member x.handle 
            with get() = _handle
            and set h = _handle <- h
    
        //Il mouseEvent associato.
        member x.event 
            with get() = _event
            and set e = _event <- e
        
        //La posizione del cursore
        member x.position 
            with get() = _pos
            and set p = _pos <- p

    let rec _mouseHandler (minfo:mouseInfo) (node:Expr) : Expr =

        let pos = minfo.position
    
        match node.Expr with
            |BigSum(p1, p2, p3) | Integral(p1, p2, p3) | Union(p1, p2, p3) | Productor(p1, p2, p3)-> 
                //debug("bigsum")
                match true with
                    | _ when p1.DrawContainer.Contains(pos) -> _mouseHandler minfo p1
                    | _ when p2.DrawContainer.Contains(pos) -> _mouseHandler minfo p2
                    | _ when p3.DrawContainer.Contains(pos) -> _mouseHandler minfo p3
                    | _ -> node
            |Sum(p1, p2) | Sub(p1, p2) | Equals(p1, p2) | Ratio(p1, p2) | Exponent(p1, p2) | Subscript(p1, p2) | Equals(p1, p2)
            |Major(p1, p2) | Minor(p1, p2) | Geq(p1, p2) | Leq(p1, p2) | Approx(p1, p2) | Sqrt(p1, p2) | Concat(p1, p2) | Limit(p1, p2)
            |LeftArrow(p1, p2) | RightArrow(p1, p2) | Mul(p1, p2)->
                match true with
                    | _ when p1.DrawContainer.Contains(pos) -> _mouseHandler minfo p1
                    | _ when p2.DrawContainer.Contains(pos) -> _mouseHandler minfo p2
                    | _ -> node
            |Round(p1) | Square(p1) | Brace(p1) | Group(p1) ->
                match true with
                    | _ when p1.DrawContainer.Contains(pos) -> _mouseHandler minfo p1
                    | _ -> node
            |Matrix(row, col, els) ->
                try
                    let el = Array.find(fun (x:Expr) -> x.DrawContainer.Contains(pos))els
                    _mouseHandler minfo el 
                with
                        | _ -> node

            |Literal(str) -> node
            | _ -> Expr(Empty)

    let mouseHandler (minfo:mouseInfo) (node:Expr) : Expr =
        let mutable result = Expr(Empty)
        if node.DrawContainer.Contains(minfo.position) then
            result <- _mouseHandler minfo node
        result
